
//从数据库获取消息及收到及时消息的处理函数

const linli = uniCloud.importObject('linliChat', {
  customUI: true
});
import soundManger from './soundManger';
import store from '../store';
import { getGridCode, getSurroundingGrids } from './getSurroundingGrids';


let sound=null

// 公共方法：生成消息存储的 key（提取重复逻辑）
function getMsgStoreKey(msg, user) {

  const { targetType, targetId } = msg.toTarget || {};
  switch (targetType) {
    case "3": // 个人会话：会话ID = 对方用户ID（自己发的消息取目标ID，别人发的取发送者ID）
      return  `person_${msg.sendUserId === user.userId ? targetId : msg.sendUserId}`  
    case "2": // 群组会话：会话ID = 群ID
      return `group_${targetId}` ;
    case "1": // 公共消息：会话ID = 网格标识
      return `public_${msg.grid}`|| '';
	 case "4":
	  return `system_${msg.id}`||''
    default:
      console.warn('未知消息类型，使用默认key', msg);
      return `unknown_${Date.now()}`;
  }
}
// 公共方法：更新会话的最后消息时间
function updateLastTime(msgStoreKey, timestamp) {
	
  if (!msgStoreKey || !timestamp) throw new Error('参数错误') ;

  // 存储结构：{ [msgStoreKey]: 最新时间戳 }
  const lastTimeStorage = uni.getStorageSync('msg_last_time') || {};
 
  // 仅保留最新的时间戳（若当前消息时间更新则覆盖）
  if (timestamp > (lastTimeStorage[msgStoreKey] || 0)) {
    lastTimeStorage[msgStoreKey] = timestamp;
	
    uni.setStorageSync('msg_last_time', lastTimeStorage);
  }
}

// 公共方法：获取会话的最后消息时间
function getLastTime(msgStoreKey) {
  const lastTimeStorage = uni.getStorageSync('msg_last_time') || {};
  return lastTimeStorage[msgStoreKey] || 0; // 默认为0（查询所有更早的消息）
}

/**
 * 清除消息的未读状态（更新本地存储）
 * @param {Object} msg - 消息对象
 * @param {Object} [user] - 当前用户信息（默认从store获取）
 */
export async function clearUnRead(msg, user = store.state.msg.user) {
	try {

		  if (!msg || !user?.userId) return; // 校验参数
	

  const msgStoreKey = getMsgStoreKey(msg, user);
  const storageKey = `msg_${msgStoreKey}`;

  // 读取本地存储（处理不存在的情况）
  let storeData = uni.getStorageSync(storageKey) || [];
  // 查找消息索引（用 timestamp + _id 双重校验，避免重复）
  const index = storeData.findIndex(
    item => item.timestamp === msg.timestamp && item._id === msg._id
  );

  if (index > -1) {
    storeData[index].isRead = true;
    uni.setStorageSync(storageKey, storeData);
    // 可选：更新store中的未读计数
    store.commit('msg/updateUnreadCount', { key: msgStoreKey, count: -1 });

  }else{
	  console.log('消除失败',storageKey);
  }
		
		
	}catch(e){
		console.error(e);
	}


}

/**
 * 保存消息到本地存储
 * @param {Object} msg - 消息对象
 * @param {Object} [user] - 当前用户信息（默认从store获取）
 * @returns {Promise} 存储结果
 */
export async function saveMsg(msg, user) {
  try {
    // 1. 优先使用传入的 user，无则从 store 获取（函数内部获取，避免默认值时机问题）
    let currentUser = user;
    if (!currentUser?.userId) {
      // 检查 store 是否存在，避免访问 undefined
      if (!store || !store.state?.msg?.user?.userId) {
        throw new Error('用户信息缺失：store 未初始化或 user 未传入');
      }
      currentUser = store.state.msg.user;
    }

    // 2. 校验核心参数（严格校验，避免无效数据）
    if (!msg || !currentUser.userId) {
      throw new Error('消息保存失败：参数无效（msg 或 userId 缺失）');
    }

    // 3. 计算存储键（复用现有逻辑）
    const msgStoreKey = getMsgStoreKey(msg, currentUser);
    const storageKey = `msg_${msgStoreKey}`;

    // 4. 格式化消息（补充默认值，避免属性缺失）
    const msgFormated = {
      ...msg,
      isRead: msg.isRead ?? false, // 空值合并运算符，更安全
      isSended: true,
      storedAt: Date.now()
    };

    // 5. 读取现有消息（同步存储，无需 await）
    const previousArray = uni.getStorageSync(storageKey) || [];
    if (!Array.isArray(previousArray)) {
      console.warn('存储的消息格式异常，重置为空数组');
      previousArray = [];
    }

    // 6. 去重（优化判断逻辑，避免遗漏）
    const isDuplicate = previousArray.some(
      item =>  item.timestamp === msg.timestamp
    );
    if (isDuplicate) {
  
      return previousArray; // 直接返回现有数组，async 自动包装为 resolved Promise
    }

    // 7. 合并并排序（保持时间顺序）
    const combinedData = [...previousArray, msgFormated]
      .sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0)); // 避免 timestamp 为 undefined

    // 8. 保存到本地存储（同步操作，无异常则继续）
    uni.setStorageSync(storageKey, combinedData);

    // 9. 更新最后消息时间（确保函数存在且无异常）
    if (typeof updateLastTime === 'function') {
      updateLastTime(msgStoreKey, msgFormated.timestamp);
    } else {
      console.warn('updateLastTime 函数未定义，跳过最后消息时间更新');
    }

    // 10. 更新未读计数（校验 store.commit 可用性）
    if (!msgFormated.isRead && store?.commit) {
      store.commit('msg/updateUnreadCount', { key: msgStoreKey, count: 1 });
    }

    // 11. 返回合并后的数据（async 自动包装为 resolved Promise）
    return combinedData;

  } catch (e) {
    console.error('消息保存失败：', e.message || e);
    // 抛出错误，让外层 catch 捕获（async 自动包装为 rejected Promise）
    throw e;
  }
}

/**
 * 获取个人消息历史并同步到本地存储
 */
export async function getPersonMsg(

  user = store.state.msg.user, 
  targetId, 
  lastTime = null, // 允许手动指定，默认用存储的最后时间
  skip = 0
) {
	console.log('per');
  try {
    if (!user?.userId || !targetId) return;

    // 生成会话key，用于获取最后时间
    const tempMsg = { toTarget: { targetType: "3", targetId }, sendUserId: user.userId };
    const msgStoreKey = getMsgStoreKey(tempMsg, user);
    // 若未手动指定lastTime，使用存储的最后时间
    const actualLastTime = lastTime ?? getLastTime(msgStoreKey);

    const personRes = await linli.getPersonMsg(user, targetId, actualLastTime, skip);
    if (personRes?.code && personRes.data?.length) {
      await Promise.all(
        personRes.data.map(msg => saveMsg(msg, user))
      );
      return personRes;
    }
  } catch (e) {
    console.error('获取个人消息失败', e);
  }
}

/**
 * 获取公共消息历史并同步到本地存储
 */
export async function getPublicMsg(location) {
  try {
    // 公共消息以网格作为会话key
    const radius = store.state.msg.stataConfig?.radius || 5;
    const currentGrid = getGridCode(location); 
    const roundGrids = getSurroundingGrids(currentGrid, radius);
    
    if (!roundGrids || roundGrids.length === 0) {
      console.warn('未获取到有效周边网格');
      return null;
    }

    // 获取本地存储的最后阅读时间
    const lastTimeStore = uni.getStorageSync('msg_last_time') || {};
    // 构建网格与时间的映射（修复逻辑错误）
    const gridAndTimeMap = roundGrids.reduce((acc, grid) => {
 
      acc[grid] = lastTimeStore[`msg_public_${grid}`] || 0;
      return acc;
    }, {});

    // 调用接口获取公共消息
    const publicRes = await linli.getPublicMsg(roundGrids, gridAndTimeMap);


    if (publicRes?.code === 0 && Array.isArray(publicRes.data) && publicRes.data.length > 0) {

      await Promise.all(
        publicRes.data.map(msg => saveMsg(msg))
      );
      return publicRes;
    }
  
    return publicRes || null;

  } catch (e) {
    console.error('获取公共消息失败', e);
    return { code: -1, message: '获取公共消息失败' };
  }
}
/**
 * 获取群消息历史并同步到本地存储
 */
export async function getGroupMsg(
 
  user = store.state.msg.user, 
  groupId, 
  lastTime = null, 
  skip = 0
) {
	
  try {
    if (!user?.userId || !groupIds?.length) return;

    // 群消息以第一个群ID作为会话key示例（实际可能需要按群单独处理）
    const tempMsg = { toTarget: { targetType: "2", targetId: groupId } };
    const msgStoreKey = getMsgStoreKey(tempMsg, user);
    const actualLastTime = lastTime ?? getLastTime(msgStoreKey);

    const groupRes = await linli.getGroupMsg(user, groupId, actualLastTime, skip);
    if (groupRes?.code && groupRes.data?.length) {
      await Promise.all(
        groupRes.data.map(msg => saveMsg(msg, user))
      );
      return groupRes;
    }
  } catch (e) {
    console.error('获取群消息失败', e);
  }
}


/**
 * 处理收到的即时消息（实时推送的新消息）
 * @param {Object} msg - 即时消息对象
 */
export async function receivMsg(msg) {
	console.log('rec',msg);
  try {
    if (!msg) return;

    const user = store.state.msg.user;
    // 1. 保存到本地存储
	store.commit('msg/SET_newMessage', {...msg,isSended:true});
    await saveMsg(msg, user);
    // 2. 触发UI更新（如聊天列表刷新、新消息提示）
   // 假设store中有对应的mutation

    // 3. 若消息是发给当前页面的会话，可自动标记为已读（可选）
    const currentChatKey = store.state.msg.currentChatKey; // 当前打开的会话key
    const msgKey = getMsgStoreKey(msg, user);

    if (currentChatKey === msgKey) {
      await clearUnRead(msg, user);
    }
	if(!sound){
		    sound=new soundManger()
	}
    const targetType=msg.toTarget.targetType
    if(msg.sendUserId===store.state.msg.user.userId){
		sound.playAction(msg.sendUserId,'send')
	}else if(targetType==='3'&&msg.sendUserId!==store.state.msg.user.userId){
		sound.playAction(msg.sendUserId,'receive')
	}else if(targetType==='2'){
		sound.playAction(msg.toTarget.targetId,'receive')
	}else if(targetType==='1'){
		const id=getFavoriteId(msg)
		sound.playAction(id,'receive')
		
	}
	
  } catch(e) {
    console.error('处理即时消息失败', e);
  }
}

/**
 * 根据消息地理位置，获取用户收藏中位于周边网格的第一个收藏ID
 * @param {Object} msg - 消息对象（需包含 location 字段，如经纬度）
 * @param {number} radius - 搜索半径（用于获取周边网格，单位根据 getSurroundingGrids 定义）
 * @returns {string|null} - 找到的收藏ID，未找到返回 null
 */
function getFavoriteId(msg) {
  // 1. 校验参数（避免传参错误导致后续报错）
  if (!msg?.location) {
    console.warn('消息缺少 location 字段，无法获取网格编码');
    return null;
  }
  const radius=store.state?.msg?.stataConfig?.radius||5  
  // 2. 获取目标位置的中心网格编码
  const centerGrid = getGridCode(msg.location);
  if (!centerGrid) {
    console.warn('无法根据 location 获取中心网格编码');
    return null;
  }

  // 3. 获取中心网格周边的所有网格编码
  const surroundingGrids = getSurroundingGrids(centerGrid, radius);
  if (!Array.isArray(surroundingGrids) || surroundingGrids.length === 0) {
    console.warn('未获取到周边网格，或返回结果不是数组');
    return null;
  }

  // 4. 获取用户所有收藏的 ID（避免直接操作 store 状态，先赋值给变量）
  const favoriteIds = store.state.msg?.user?.favorite?.map(item => item.favorite_id) || [];
  if (favoriteIds.length === 0) {
    console.warn('用户暂无收藏');
    return null;
  }

  // 5. 循环匹配：找到第一个在周边网格内的收藏 ID
  let targetFavoriteId = null;
  for (const favoriteId of favoriteIds) {
    // 关键：检查收藏 ID 是否在周边网格数组中（需确保 favoriteId 是字符串/数字，与 grids 元素类型一致）
    if (surroundingGrids.includes(favoriteId)) {
      targetFavoriteId = favoriteId;
      break; // 找到第一个匹配项就退出循环（符合原逻辑）
    }
  }

  // 6. 打印结果（方便调试）
  if (targetFavoriteId) {
    console.log(`找到匹配的收藏 ID：${targetFavoriteId}（位于周边网格：${surroundingGrids.join(',')}）`);
  } else {
    console.log(`未在周边网格（${surroundingGrids.join(',')}）中找到用户收藏`);
  }

  return targetFavoriteId;




 }